home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2007 December / PCWKCD1207B.iso / Blogowanie poza sfera / Flock 0.9.1.3 stable / flock-0.9.1.3.en-US.win32.exe / flock / yahootoolbar.xpi / components / nsYahooFeedProcessor.js < prev    next >
Text File  |  2007-01-12  |  25KB  |  751 lines

  1. /*
  2.  * Copyright 2005 - 2006 Yahoo! Inc. All rights reserved.
  3.  */
  4. function nsIYahooFeedProcessor(){}
  5. nsIYahooFeedProcessor.prototype = {
  6.     NOT_LOADED : 0x01,
  7.     CACHE_LOADED : 0x02,
  8.     LIVE_LOADED : 0x03,
  9.     feedVer : "4",
  10.     clientVer : "1.0.0",
  11.     clientID : null,
  12.     country : "us",
  13.     lang : "us",
  14.     corp : "",
  15.     partner : "",
  16.     FEED_URL : "http:\/\/us.update2.toolbar.yahoo.com/slv/v4/2.html?&.pc=&t=1123627243899&.ta=cgnone,cc,cius,cv1_1_0,cp,cbm",
  17.     loads : 0,
  18.     loaded : false,
  19.     loading : false,
  20.     loadedType : this.NOT_LOADED,
  21.     isGuest : true,
  22.     cacheFile : null,
  23.     raw : null,
  24.     params : null,
  25.     values : null,
  26.     domBuilder : null,
  27.     styles : { "std" : {
  28.                     1 : "OUTLINE", 2 : "ROUNDEDGE", 4 : "HIGHLIGHT", 8 : "RAISED", 16 : "STATIC", 32 : "TOGGLE", 64 : "MODIFIABLE", 
  29.                     128 : "LOCAL", 256 : "NOMENUHIDE", 512 : "NOTEXT", 1024 : "NOMORE", 2048 : "REMOVEONCLICK", 4096 : "TOGGLEOFF",
  30.                     8192 : "MINIMIZABLE", 16384 : "REDIRECT", 32768 : "MENUITEM", 65536 : "NOUSECACHE", 131072 : "NOTOOLTIP", 
  31.                     262144 : "ALWAYSPRESSED", 524288 : "ANIMATED", 1048576 : "ALWAYSHIDE", 2097152 : "BROWSERIMAGE" 
  32.                 },
  33.                 "ext" : {
  34.                     1 : "EX_ALIGNCENTER", 2 : "EX_ALIGNRIGHT", 4 : "EX_MODUSERES", 4 : "EX_MODUSERES", 8 : "EX_MODUSERPAR", 
  35.                     16 : "EX_TBLINEFEED", 32 : "EX_TBNOCLOSE", 64 : "EX_TBNOGETMOD", 128 : "EX_TBPASSEDIT", 256 : "EX_TBFORCEGETMOD",
  36.                     8192 : "EX_ENABLEDBY", 65536 : "EX_ENABLEDBY", 131072 : "EX_NEWWINDOWTAB"
  37.                 }
  38.             },
  39.     loadingAlerts : false,
  40.     code : [],
  41.     charsets : [],
  42.     notifier : null,
  43.     stream : null,
  44.     size : 0,
  45.     timer : null,
  46.     bm2timer : null,
  47.     uniconvert : null,
  48.     acs : null,
  49.     init : function() {
  50.         if(this.loaded == false){
  51.             this.notifier = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
  52.             this.uniconvert = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
  53.             this.uniconvert.charset = 'utf-8';
  54.             this.params = Components.classes["@yahoo.com/feed/hashtable;1"].createInstance(Components.interfaces.nsIYahooHashtable);
  55.             this.values = Components.classes["@yahoo.com/feed/hashtable;1"].createInstance(Components.interfaces.nsIYahooHashtable);
  56.             this.domBuilder = Components.classes["@yahoo.com/dombuilder;1"].getService(Components.interfaces.nsIYahooDomBuilder);
  57.             this.code[0x01] = String.fromCharCode(0x01);
  58.             this.code[0x02] = String.fromCharCode(0x02);
  59.             this.code[0x03] = String.fromCharCode(0x03);
  60.             this.code[0x04] = String.fromCharCode(0x04);
  61.             this.code[0x05] = String.fromCharCode(0x05);
  62.             this.code[0x06] = String.fromCharCode(0x06);
  63.             this.code[0x07] = String.fromCharCode(0x07);
  64.             this.code[0x08] = String.fromCharCode(0x08);
  65.             this.code[0x09] = String.fromCharCode(0x09);
  66.             this.code[0x14] = String.fromCharCode(0x14);
  67.             this.code[0x15] = String.fromCharCode(0x15);
  68.             this.code[0x16] = String.fromCharCode(0x16);
  69.             this.code[0x17] = String.fromCharCode(0x17);
  70.             this.code[0x18] = String.fromCharCode(0x18);
  71.             this.code[0x19] = String.fromCharCode(0x19);
  72.             this.charsets[1]   = 'iso-8859-1';   
  73.             this.charsets[128] = 'shift_jis';    
  74.             this.charsets[129] = 'euc-kr';       
  75.             this.charsets[130] = 'johab';        
  76.             this.charsets[134] = 'gb2312';       
  77.             this.charsets[136] = 'Big5';         
  78.             this.charsets[161] = 'windows-1253'; 
  79.             this.charsets[162] = 'windows-1254'; 
  80.             this.charsets[163] = 'windows-1258'; 
  81.             this.charsets[177] = 'windows-1255'; 
  82.             this.charsets[178] = 'windows-1256'; 
  83.             this.charsets[186] = 'windows-1257'; 
  84.             this.charsets[204] = 'windows-1251'; 
  85.             this.charsets[222] = 'windows-874';  
  86.             this.charsets[238] = 'windows-1250'; 
  87.             try{
  88.                 this.cacheFile = Components.classes["@mozilla.org/file/directory_service;1"].createInstance(Components.interfaces.nsIProperties);
  89.                 this.cacheFile = this.cacheFile.get("PrefD", Components.interfaces.nsILocalFile);
  90.                 this.cacheFile.appendRelativePath("extensions");
  91.                 this.cacheFile.appendRelativePath("{635abd67-4fe9-1b23-4f01-e679fa7484c1}");
  92.                 if(!this.cacheFile.exists()){
  93.                     this.cacheFile.create(Components.interfaces.nsILocalFile.DIRECTORY_TYPE, 0777);
  94.                 }
  95.                 this.cacheFile.appendRelativePath("cache");
  96.                 if(!this.cacheFile.exists()){
  97.                     this.cacheFile.create(extd.DIRECTORY_TYPE, 0777);
  98.                 }
  99.                 this.cacheFile.appendRelativePath("feed");
  100.             } catch(e){ this.notifier.notifyObservers(null, "yahoo-feed-error", "400: "+ e); }
  101.             this.loadFeed(true);
  102.             this.loaded = true;
  103.         }
  104.     },
  105.     run : function(){
  106.         this.load(false);
  107.     },
  108.     buildFeedUrl : function(type){
  109.         var param;
  110.         var url = "";
  111.         var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
  112.         var fnum    = 2; 
  113.         var fver    = 4; 
  114.         var time    = (new Date().getTime());
  115.         var cc         = (prefs.prefHasUserValue("yahoo.installer.country")) ? prefs.getCharPref("yahoo.installer.country") +"." : "us.";
  116.         var pc         = (prefs.prefHasUserValue("yahoo.installer.pc")) ? prefs.getCharPref("yahoo.installer.pc") : "";
  117.         var tid        = (prefs.prefHasUserValue("yahoo.installer.toolbarID")) ? prefs.getCharPref("yahoo.installer.toolbarID") : "";
  118.         var cid        = (prefs.prefHasUserValue("yahoo.installer.corpID")) ? prefs.getCharPref("yahoo.installer.corpID") : "";
  119.         var lang    = (prefs.prefHasUserValue("yahoo.installer.language")) ? prefs.getCharPref("yahoo.installer.language") : cc;
  120.         var cver    = (prefs.prefHasUserValue("yahoo.installer.version")) ? prefs.getCharPref("yahoo.installer.version") : "1.1.0";
  121.         if(!this.isGuest && (param = this.params.get("lang")) != null){
  122.             lang = param.func;
  123.         }
  124.         if(tid == ""){
  125.             tid = "none";
  126.         }
  127.         if(cver != ""){
  128.             cver = cver.split(".");
  129.             if(cver.length > 3){
  130.                 cver.length = 3;
  131.             }
  132.             cver = cver.join("_");
  133.         }
  134.         if(type == 0){
  135.             url = "http:\/\/"+ cc +"update2.toolbar.yahoo.com"+
  136.                     "/slv/v"+ fver +
  137.                     "/"+ fnum +".html"+
  138.                     "?&.pc="+ pc +
  139.                     "&t="+ time + 
  140.                     "&.ta=cg"+ tid + 
  141.                     ",cc"+ cid + 
  142.                     ",ci"+ lang + 
  143.                     ",cv"+ cver + 
  144.                     ",cp"+ pc +
  145.                     ",cbm";
  146.         }
  147.         else{
  148.             url = "http:\/\/"+ cc +"update.companion.yahoo.com"+
  149.                     "/slv/v"+ fver + 
  150.                     "/not?v="+ cver +
  151.                     "&t="+ time +
  152.                     "&.ta=cg"+ tid +
  153.                     ",cc"+ cid +
  154.                     ",ci"+ lang +
  155.                     ",cv"+ cver;
  156.         }
  157.         return url;
  158.     },
  159.     loadFeed : function(async){
  160.         var cookies;
  161.         try{
  162.             this.loading = true;
  163.             this.loadingAlerts = false;
  164.             this.isGuest = true;
  165.             cookies = Components.classes["@mozilla.org/cookiemanager;1"].getService(Components.interfaces.nsICookieManager2);
  166.             cookies = cookies.enumerator;
  167.             while(cookies.hasMoreElements()) {
  168.                 var cookie = cookies.getNext().QueryInterface(Components.interfaces.nsICookie);
  169.                 if(cookie.host == ".yahoo.com" && cookie.name == "Y") {
  170.                     if(cookie.value != null &&
  171.                             (cookie.value.search(/l=[^&]/) > -1 || cookie.value.indexOf("np=1") > -1)){
  172.                         this.isGuest = false;
  173.                     }
  174.                     break;
  175.                 }
  176.             }
  177.             this.FEED_URL = this.buildFeedUrl(0);
  178.             var iosvc = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
  179.             var channel = iosvc.newChannel(this.FEED_URL, 0, null);
  180.             channel.asyncOpen(this, null);
  181.         } catch(e){ this.notifier.notifyObservers(null, "yahoo-feed-error", "405: "+ e); }
  182.         cookies = null;
  183.         this.loading = false;
  184.     },
  185.     loadCachedFeed : function(){
  186.         var inStream, handle;
  187.         try{
  188.             this.loadedType = this.CACHE_LOADED;
  189.             this.notifier.notifyObservers(null, "yahoo-feed-loading-cached", null);
  190.             if(this.cacheFile.exists()){        
  191.                 inStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
  192.                 inStream.init(this.cacheFile, 0x01, 0666, 0);
  193.                 handle = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
  194.                 handle.init(inStream);
  195.                 var size = 0;
  196.                 this.raw = "";
  197.                 while(size = inStream.available()) {
  198.                     this.raw += handle.read(size);
  199.                     this.size += size;
  200.                 }
  201.             }
  202.             else{
  203.                 this.notifier.notifyObservers(null, "yahoo-feed-error", "409: No cache file"); 
  204.                 return false;
  205.             }
  206.             if(this.size < 0){
  207.                 this.notifier.notifyObservers(null, "yahoo-feed-error", "408: Empty cache"); 
  208.                 return false;
  209.             }
  210.             this.processFeed();
  211.             this.notifier.notifyObservers(this, "yahoo-feed-updated", null);
  212.         }catch(e){
  213.             this.notifier.notifyObservers(null, "yahoo-feed-error", "407: "+ e); 
  214.         }
  215.         if(handle){
  216.             handle.close();
  217.         }
  218.         if(inStream){
  219.             inStream.close();
  220.         }
  221.     },
  222.     onStartRequest: function(request, context) {
  223.         this.size = 0;
  224.         this.raw = "";
  225.     },
  226.     onDataAvailable: function(request, context, inputStream, offset, count) {
  227.         if(this.stream == null){
  228.             this.stream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
  229.         }
  230.         this.stream.init(inputStream);  
  231.         this.raw += this.stream.read(count);
  232.     },
  233.     onStopRequest: function(request, context, statusCode) {
  234.         var http;
  235.         try{
  236.             if(this.stream != null){
  237.                 try{ this.stream.close(); }catch(e){}
  238.                 this.stream = null;
  239.             }
  240.             http = request.QueryInterface(Components.interfaces.nsIHttpChannel);
  241.             if(this.raw == "" || http.status != 0) {
  242.                 this.loadCachedFeed();
  243.                 return;
  244.             }
  245.             this.size = this.raw.length;
  246.             this.processFeed();
  247.             this.cacheFeed();
  248.             this.loadedType = this.LIVE_LOADED;
  249.             this.notifier.notifyObservers(this, "yahoo-feed-updated", null);
  250.             if(this.domBuilder.bm2Feed){
  251.                 this.processBM2();
  252.             }
  253.             else{
  254.             }
  255.             try{
  256.                 if(this.timer == null){
  257.                     var delay = 1000 * 60 * 7; 
  258.                     var processor = this;
  259.                     var callback = { 
  260.                         notify : function(timer){ processor.retrieveAlerts(); }
  261.                     };
  262.                     this.timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
  263.                     this.timer.initWithCallback(callback, delay, this.timer.TYPE_REPEATING_PRECISE);
  264.                 }
  265.             } catch(e){
  266.                 this.notifier.notifyObservers(null, "yahoo-feed-warning", "405: "+ e); 
  267.             }
  268.             try{
  269.                 if(this.bm2timer == null){
  270.                     var delay = 1000 * 60 * 60; 
  271.                     var processor = this;
  272.                     var callback = { 
  273.                         notify : function(bm2timer){ 
  274.                             var str = processor.domBuilder.getBM2UsageString();
  275.                             if(str.length > 0) { 
  276.                                 processor.processBM2(); 
  277.                             } 
  278.                         }
  279.                     };
  280.                     this.bm2timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
  281.                     this.bm2timer.initWithCallback(callback, delay, this.bm2timer.TYPE_REPEATING_PRECISE);
  282.                 }
  283.             } catch(e){
  284.                 this.notifier.notifyObservers(null, "yahoo-feed-warning", "405: "+ e); 
  285.             }
  286.         } catch(e) { 
  287.             this.loadedType = this.NOT_LOADED;
  288.             this.notifier.notifyObservers(null, "yahoo-feed-error", "403: "+ e); 
  289.         } 
  290.         http = null;
  291.         request = null;
  292.         context = null;
  293.         this.loading = false;
  294.     },
  295.     cacheFeed : function(){
  296.         if(this.raw != null && this.raw != ""){
  297.             try{
  298.                 if(this.cacheFile != null && this.isGuest){        
  299.                     if(!this.cacheFile.exists()){
  300.                         this.cacheFile.create(this.cacheFile.NORMAL_FILE_TYPE, 0666);
  301.                     }
  302.                     var out = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
  303.                     out.init(this.cacheFile, 0x20 | 0x02, 00666, null); 
  304.                     out.write(this.raw, this.raw.length);
  305.                     out.flush();
  306.                     out.close();
  307.                 }
  308.             } catch(e){ this.notifier.notifyObservers(null, "yahoo-feed-error", "440: "+ e); } 
  309.         }
  310.     },
  311.     clear : function(){    
  312.         this.domBuilder.clear();
  313.         this.params.clear();
  314.         this.values.clear();
  315.     },
  316.     processFeed : function(){
  317.         if(this.raw != null && this.raw != ""){
  318.             this.clear();
  319.             var pos = 0;
  320.             while(pos < this.size){
  321.                 pos = this.readNextNode(null, pos); 
  322.             }            
  323.             pos = null;
  324.             this.loads++;
  325.         }
  326.         else{
  327.             throw "No feed data";
  328.         }
  329.     },
  330.     readNextNode : function(parent, pos){
  331.         try{
  332.             var first = this.raw.charAt(pos++);
  333.             if(first != this.code[0x14] && first != this.code[0x16]){
  334.                 return pos;
  335.             }
  336.             var ch;
  337.             var num = 0; 
  338.             var param = "";
  339.             var params = new Array();
  340.             while(pos < this.size){
  341.                 ch = this.raw[pos++];
  342.                 if(first == this.code[0x16]){
  343.                     if(num == 0){
  344.                         params[0] = "";
  345.                         num++;
  346.                     }
  347.                     else if(num == 2){
  348.                         params[2] = this.code[0x16];
  349.                         params[3] = "";
  350.                         num += 2;
  351.                     }
  352.                     else if(num == 10){
  353.                         params[10] = "";
  354.                         num++;
  355.                     }
  356.                 }
  357.                 if(ch == this.code[0x19]){
  358.                     params[num++] = param;
  359.                     param = "";
  360.                     break;
  361.                 }
  362.                 else if(ch == this.code[0x18]){
  363.                     params[num++] = param;
  364.                     param = "";
  365.                 }
  366.                 else{
  367.                     param += ch;
  368.                 }
  369.             }
  370.             if(num > 1){
  371.                 var node = Components.classes["@yahoo.com/feed/node;1"].createInstance(Components.interfaces.nsIYahooFeedNode);
  372.                 node.name = params[1];
  373.                 node.type = params[2].charCodeAt(0);
  374.                 if(node.type == node.VALUE_TYPE){
  375.                     this.values.addString(node.name, params[3]);
  376.                     node = null;
  377.                 }
  378.                 else{
  379.                     node.icon = params[3];
  380.                     node.func = params[4];
  381.                     if(node.func != ""){
  382.                         node.func = node.func.replace(/,/g, "%2C"); 
  383.                         var func = node.func.split(this.code[0x01]);
  384.                         node.func = func.join(",");
  385.                         if(func.length > 1){
  386.                             node.funcNum = parseInt(func[1], 10);
  387.                             if(func.length > 2){
  388.                                 node.funcTracking = func[2];
  389.                             }
  390.                             if(func.length > 3){        
  391.                                 func.splice(0,3);
  392.                                 node.funcUrl = func.join(",");
  393.                             }
  394.                         }
  395.                         else if(func.length == 1){
  396.                             node.funcNum = -1;
  397.                             node.funcUrl = func[0];
  398.                         }
  399.                         func = null;
  400.                     }
  401.                     if(node.type == node.PARAM_TYPE && node.name == "lang" && isFinite(node.icon)){
  402.                         this.uniconvert.charset = this.charsets[node.icon];
  403.                         this.raw = this.uniconvert.ConvertToUnicode(this.raw);
  404.                     }
  405.                     if(node.type != node.PARAM_TYPE){
  406.                         this.cacheIcon(node);
  407.                     }
  408.                     if(node.type == 0x05){
  409.                         node.type = node.BUTTONMENU_TYPE
  410.                     }
  411.                     else if( node.name == "-" || node.icon == "vsep" || node.name == "spr" ||  node.name == "sep"){
  412.                         node.type = node.SEPARATOR_TYPE;
  413.                     }
  414.                     var styles = 0;
  415.                     if(num > 5 && params[5] != ""){
  416.                         styles = params[5];
  417.                     }
  418.                     var extStyles = 0;
  419.                     if(num > 7 && params[7] != ""){
  420.                         extStyles = params[7];
  421.                     }
  422.                     this.processStyles(node, styles, extStyles);
  423.                     if(num > 12 && params[12] != ""){
  424.                         params[12] = params[12].split("&");
  425.                         for(var i = 0; i < params[12].length; i++){
  426.                             params[12][i] = params[12][i].split("=");
  427.                             if(params[12][i].length > 1){
  428.                                 if(params[12][i][0] == "icov"){
  429.                                     node.icon = params[12][i][1];
  430.                                     this.cacheIcon(node);
  431.                                 }
  432.                                 else if(params[12][i][0] == "id"){
  433.                                     node.id = params[12][i][1].replace(/g_/g, "_"); 
  434.                                 }
  435.                                 params[12][i][1] = params[12][i][1].replace(/\\/g, "\\\\");
  436.                                 params[12][i][1] = params[12][i][1].replace(/'/g, "\\'");
  437.                                 // Add to JSON object
  438.                                 params[12][i] = "'"+ params[12][i][0] +"':'"+ params[12][i][1] +"'";
  439.                             }
  440.                             else{
  441.                                 params[12][i] = "'"+ params[12][i][0] +"':true";
  442.                             }
  443.                             node.hash += ((i > 0) ? ",": "") + params[12][i];
  444.                         }
  445.                     }
  446.                     // Add namespace to ID
  447.                     if(node.id != null){
  448.                         node.id = ((parent != null && parent.id) ? parent.id : "yahoo-toolbar") +"-"+ node.id;
  449.                     }
  450.                     // REVIEW NOTE: explains 'added'
  451.                     var added = false;
  452.                     // Add node to array
  453.                     if(parent == null && node.type == node.PARAM_TYPE){
  454.                         this.params.add(node.name, node);
  455.                         if(node.id != "yahoo-toolbar-acs"){
  456.                             added = true;
  457.                         }
  458.                     }
  459.                     else if(parent != null && parent instanceof Components.interfaces.nsIYahooFeedNode){
  460.                         parent.addChild(node);
  461.                     }
  462.                     // Reassign parent to DOM Node
  463.                     if(parent != null && parent.domToolbar != null){
  464.                         parent = parent.domToolbar;
  465.                     }
  466.                     else if(parent instanceof Components.interfaces.nsIYahooFeedNode){
  467.                         parent = null;
  468.                     }
  469.                     // Child nodes
  470.                     while(pos < this.size && this.raw[pos] != this.code[0x15] && this.raw[pos] != this.code[0x17]){
  471.                         // Add node to DOM
  472.                         if(added == false && node != null){
  473.                             // Make this a menu (since it's not explicitly set in feed)
  474.                             switch(node.type){
  475.                                 case node.BUTTON_TYPE:
  476.                                     node.type = node.BUTTONMENU_TYPE;
  477.                                 break;
  478.                                 case node.MENUITEM_TYPE:
  479.                                     node.type = node.MENU_TYPE;
  480.                                 break;
  481.                             }
  482.                             node.domToolbar = this.domBuilder.addNode(node, parent);
  483.                             added = true;
  484.                         }
  485.                         // Recurse into child
  486.                         pos = this.readNextNode(node, pos);
  487.                     }
  488.                     // Create DOM node -- if haven't already
  489.                     //     - ignore if it's a menu, because if it hasn't been added already, then there aren't any children
  490.                     if(added == false && node.type != node.MENU_TYPE && node.type != node.BUTTONMENU_TYPE){
  491.                         node.domToolbar = this.domBuilder.addNode(node, parent);
  492.                     }
  493.                 }
  494.                 pos++;
  495.                 if(node != null && node.type != node.PARAM_TYPE){
  496.                     node.destroy();
  497.                 }
  498.                 node = null;
  499.                 ch = null;
  500.                 num = null;
  501.                 first = null;
  502.                 param = null;
  503.                 params = null;
  504.             }
  505.         } catch(e){
  506.             this.notifier.notifyObservers(null, "yahoo-feed-warning", "420: "+ e);
  507.         }
  508.         parent = null;
  509.         return pos;
  510.     },
  511.     /**
  512.     * Process the feed style codes
  513.     * @param {nsIYahooFeedNode} node The feed node to with style data
  514.     * @param {int} styles The styles flag
  515.     * @param {int} extStyles The extended styles flag
  516.     */
  517.     processStyles : function(node, styles, extStyles){
  518.         var bit = 0;
  519.         var nodeStyles = ",";
  520.         var stdBits = this.styles.std;
  521.         var extBits = this.styles.ext;
  522.         try{
  523.             // No styles
  524.             if(styles == 0 && extStyles == 0){
  525.                 return;
  526.             }
  527.             // Standard styles
  528.             var key;
  529.             if(styles > 0){
  530.                 for(key in this.styles.std){
  531.                     if(styles & key){
  532.                         nodeStyles += stdBits[key] +",";
  533.                     }
  534.                 }
  535.             }
  536.             // Extended
  537.             var key;
  538.             if(extStyles > 0){
  539.                 for(key in extBits){
  540.                     if(extStyles & key){
  541.                         nodeStyles += extBits[key] +",";
  542.                     }
  543.                 }
  544.             }
  545.             node.styles = nodeStyles;
  546.         } catch(e) {
  547.         }
  548.     },
  549.     /**
  550.     * Cache the node's icon
  551.     * @param {nsIYahooFeedNode} node The node with the icon to cache
  552.     */
  553.     cacheIcon : function(node){
  554.         var path = "http:\/\/us.i1.yimg.com/us.yimg.com/i/tb/iconsgif/";
  555.         var icon = node.icon;
  556.         if(icon == ""){
  557.             return "";
  558.         }
  559.         // Chrome URL
  560.         if(icon.indexOf(".") < 0){
  561.             node.icon = "chrome:\/\/ytoolbar/skin/"+ icon + ".gif";
  562.         }
  563.         // External Icon
  564.         else{
  565.             icon = icon.replace(/\.bmp$/i, ".gif");
  566.             path += icon;
  567.             node.icon = path;
  568.         }
  569.     },
  570.     /**
  571.     * Get Alerts (i.e new mail) from the server for a logged-in user.
  572.     * When the alert feed has been read, the <b>yahoo-feed-alert</b> notification will be sent.
  573.     */
  574.     retrieveAlerts : function(){
  575.         try{
  576.             // User not logged in
  577.             if(this.isGuest){
  578.                 return;
  579.             }
  580.             this.loadingAlerts = true;
  581.             var url = this.buildFeedUrl(1);
  582.             var processor = this;
  583.             // Make request
  584.             var iosvc = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
  585.             var channel = iosvc.newChannel(url, 0, null);        
  586.             var channelListener = {
  587.                 stream : null,
  588.                 onStartRequest: function(request, context) {
  589.                     processor.raw = "";
  590.                 },
  591.                 onDataAvailable: function(request, context, inputStream, offset, count) {
  592.                     if(this.stream == null){
  593.                         this.stream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
  594.                     }
  595.                     this.stream.init(inputStream);
  596.                     processor.raw += this.stream.read(count);
  597.                 },
  598.                 // Process returned feed
  599.                 onStopRequest: function(request, context, statusCode) {
  600.                     try{
  601.                         if(this.stream != null){
  602.                             this.stream.close();
  603.                         }
  604.                         request.QueryInterface(Components.interfaces.nsIHttpChannel);
  605.                         // load error
  606.                         if(processor.raw == "" || request.status != 0) {
  607.                             return;
  608.                         }
  609.                         // Encode to utf-8
  610.                         if(processor.uniconvert.charset != "utf-8"){
  611.                             processor.raw = processor.uniconvert.ConvertToUnicode(processor.raw);
  612.                         }
  613.                         // Empty alerts
  614.                         while(processor.domBuilder.alerts.firstChild){
  615.                             processor.domBuilder.alerts.removeChild(processor.domBuilder.alerts.firstChild);
  616.                         }
  617.                         // Get alert nodes from feed
  618.                         var pos = 0;
  619.                         var len = processor.raw.length;
  620.                         while(processor.loadingAlerts && pos < len){
  621.                             pos = processor.readNextNode(processor.domBuilder.alerts, pos); 
  622.                         }
  623.                         processor.loadingAlerts = false;
  624.                         // Notify toolbar of new alerts
  625.                         processor.notifier.notifyObservers(null, "yahoo-feed-alerts-updated", processor.domBuilder.alerts.childNodes.length);
  626.                     } catch(e) {
  627.                         processor.notifier.notifyObservers(null, "yahoo-feed-warning", "451: "+ e); 
  628.                     }
  629.                     this.stream = null;
  630.                     processor = null
  631.                 }
  632.             };
  633.             channel.asyncOpen(channelListener, null);
  634.         } catch(e){
  635.             processor.notifier.notifyObservers(null, "yahoo-feed-warning", "451: "+ e); 
  636.         }
  637.     },
  638.     /**
  639.     * Process and build the Bookmarks 2.0 list
  640.     */
  641.     processBM2 : function(){
  642.         try{
  643.             // No feed URL
  644.             if(!this.domBuilder.bm2Feed || this.domBuilder.bm2Feed == ""){
  645.                 return;
  646.             }
  647.             var self = this;
  648.             var iosvc = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
  649.             var bm2url = this.domBuilder.bm2Feed;
  650.             var str = this.domBuilder.getBM2UsageString();
  651.             if(str.length > 0) {
  652.                 bm2url += "&docids=" + str;
  653.                 this.domBuilder.clearBM2Usage();
  654.             }
  655.             var channel = iosvc.newChannel(bm2url, 0, null);
  656.             var listen = {
  657.                 stream : null,
  658.                 xml : "",
  659.                 onStartRequest: function(request, context) {
  660.                     this.xml = "";
  661.                 },
  662.                 onDataAvailable: function(request, context, inputStream, offset, count) {
  663.                     if(this.stream == null){
  664.                         this.stream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
  665.                     }
  666.                     this.stream.init(inputStream); 
  667.                     this.xml += this.stream.read(count);
  668.                 },
  669.                 onStopRequest: function(request, context, statusCode) {
  670.                     var http;
  671.                     try{
  672.                         if(this.stream != null){
  673.                             // Try to close if initialized
  674.                             try{ this.stream.close(); }catch(e){}
  675.                             this.stream = null;
  676.                         }
  677.                         // REVIEW NOTE: what is in statusCode ^
  678.                         http = request.QueryInterface(Components.interfaces.nsIHttpChannel);
  679.                         // Build bookmarks
  680.                         if(this.xml != "" && http.status == 0) {
  681.                             var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"].createInstance(Components.interfaces.nsIDOMParser);
  682.                             var doc = parser.parseFromString(this.xml, "text/xml");
  683.                             var root = doc.getElementsByTagName("outline");
  684.                             if(root.length > 0){
  685.                                 self.domBuilder.clearBM2();
  686.                                 self.domBuilder.buildBM2(root[0], null);
  687.                                 self.notifier.notifyObservers(null, "yahoo-feed-bookmarks-updated", null);
  688.                                 self.debug("Nodes: "+ self.domBuilder.bookmarks.childNodes.length);
  689.                             }
  690.                         }
  691.                     } catch(e){
  692.                         self.debug("ERROR in processBM2.onStopRequest(): "+ e);
  693.                     }
  694.                 }
  695.             }
  696.             channel.asyncOpen(listen, null);
  697.         } catch(e){
  698.         }
  699.     },
  700.     /** 
  701.     * Uses the DebugLogger Mozmonkey extension to log messages (Tools -> DebugLogger)
  702.     * @private 
  703.     */
  704.     debug : function(msg){
  705.         if(typeof(Components.interfaces.nsIDebugLoggerManager) != 'undefined'){
  706.             logMngr = Components.classes["@mozmonkey.com/debuglogger/manager;1"].getService(Components.interfaces.nsIDebugLoggerManager);
  707.             //var d = new Date();
  708.             //var time = d.getHours() +":"+ d.getMinutes() +":"+ d.getSeconds();
  709.             logger = logMngr.registerLogger("yfeedtest");
  710.             logger.log(3, msg);
  711.         }
  712.     },
  713.     /* DO NOT CHANGE */
  714.     QueryInterface: function (iid) {
  715.         if(!iid.equals(Components.interfaces.nsIYahooFeedProcessor) && !iid.equals(Components.interfaces.nsISupports) && !iid.equals(Components.interfaces.nsIRunnable))
  716.             throw Components.results.NS_ERROR_NO_INTERFACE;
  717.         return this;
  718.     }
  719. };
  720. /** 
  721. * DO NOT CHANGE THIS OBJECT 
  722. * @private
  723. */
  724. function NSGetModule(compMgr, fileSpec) {
  725.     return {
  726.         myCID         : Components.ID("{4138788A-68DF-4cb5-B6F9-E50DE9C70708}"),
  727.         myProgID     : "@yahoo.com/feed/processor;1",
  728.         firstTime    : true,
  729.         registerSelf : function (compMgr, fileSpec, location, type) {
  730.             if (this.firstTime) {
  731.                 this.firstTime = false;
  732.                 throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
  733.             }
  734.             compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  735.             compMgr.registerFactoryLocation(this.myCID, "Yahoo! Feed Processor", this.myProgID, fileSpec, location, type);
  736.         },
  737.         getClassObject : function (compMgr, cid, iid) {
  738.             if (!cid.equals(this.myCID)) throw Components.results.NS_ERROR_NO_INTERFACE;
  739.             if (!iid.equals(Components.interfaces.nsIFactory)) throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  740.             return this.myFactory;
  741.         },
  742.         myFactory : {
  743.             createInstance : function (outer, iid) {
  744.                 if (outer != null) throw Components.results.NS_ERROR_NO_AGGREGATION;
  745.                 return (new nsIYahooFeedProcessor()).QueryInterface(iid);
  746.             }
  747.         },
  748.         canUnload : function(compMgr) { return true; }
  749.     };
  750. }
  751.